#include "groundwvudp.h"

GroundWVUdp::GroundWVUdp(int width, int height, QObject *parent) : UdpBase(parent)
{
    m_imgFirstBytes = width * 2 + 8;
    m_imgAllBytes = width * height * 2;
    m_totalPackets = height;

    //帧率控制模块初始化
    //计算定时器周期（ms）：1000ms / 目标帧率
    int interval = 1000 / m_targetFps;
    m_sendTimer.setInterval(interval);

    //定时器单次触发（避免队列空时重复触发）
    m_sendTimer.setSingleShot(false);

    //绑定定时器触发信号：从队列取帧并发送给编码端
    connect(&m_sendTimer, &QTimer::timeout, this, &GroundWVUdp::onSendFrameToEncoder);

    m_sendTimer.start();
}

GroundWVUdp::~GroundWVUdp()
{

}

void GroundWVUdp::startProcess()
{
    m_runStatus = true;
}

void GroundWVUdp::stopProcess()
{
    m_runStatus = false;
}

void GroundWVUdp::onInitUdp()
{
    m_udpReceive = new QUdpSocket(this);
    if (m_udpReceive->bind(m_bindPort, QUdpSocket::ShareAddress)) {
        connect(m_udpReceive, &QUdpSocket::readyRead, this, &GroundWVUdp::onReceive);
        qDebug() << QString("广播成功，正在监听端口%1").arg(m_bindPort);
    } else {
        qWarning() << "绑定失败!" << m_bindIP << ":" << m_bindPort ;
    }

    //获取网卡对应的index
    QNetworkInterface netInterface = getNetInterface(m_bindIP);
    m_netCardIndex = getNetCardIndex(netInterface.name());
    if(m_netCardIndex == -1) {
        qDebug() << QString("%1网卡的index获取失败").arg(netInterface.name());
    }
}

void GroundWVUdp::onReceive()
{
    while (m_udpReceive->hasPendingDatagrams() && m_runStatus) {

        //qDebug() << "接收到数据";
        QNetworkDatagram datagram = m_udpReceive->receiveDatagram();

//        // 每收到一行数据，帧数加1
//        m_frameCount++;

//        // 检查是否已经超过1秒，计算帧率
//        if (m_fpsTimer.elapsed() >= 1000) {
//            m_currentFps = m_frameCount * 1000.0 / m_fpsTimer.elapsed();
//            qDebug() << "udp的接收帧率" << m_currentFps / 256;

//            // 重置计时器和计数器
//            m_fpsTimer.restart();
//            m_frameCount = 0;
//        }

        //如果是广播方式，在多网卡情况下，需要获取当前绑定网卡的index，来和收到的网卡的index对比，如果
        //不一致则舍弃，避免重复接收
//         if(datagram.interfaceIndex() != static_cast<uint>(m_netCardIndex)) {
//             continue;
//         }

        QString srcIp = datagram.senderAddress().toString().section(":", -1);
        //quint16 srcPort = static_cast<quint16>(datagram.senderPort());

        if(srcIp != m_srcIP || datagram.data().size() <= 8) {
            continue;
        }

        processSlice(datagram.data());
    }
}

void GroundWVUdp::onSendFrameToEncoder()
{
    QMutexLocker locker(&m_queueMutex); // 加锁保护队列

    // 队列有帧时，取首帧发送；无帧时跳过
    if (!m_frameQueue.isEmpty()) {
        QByteArray frameData = m_frameQueue.dequeue();
        emit sigToEncodeImg(frameData);
    } else {
        // 队列空时打印，判断是否是编码端消费过快或UDP接收丢包
        qDebug() << "Frame queue is empty! No frame to send";
    }
}

void GroundWVUdp::processSlice(const QByteArray &data)
{
    if (static_cast<quint8>(data[0]) == 0xF0 && static_cast<quint8>(data[1]) == 0x5A &&
            static_cast<quint8>(data[2]) == 0xA5 && static_cast<quint8>(data[3]) == 0x0F) {

            // 验证第一个分片是否为正确字节
        if (data.size() != m_imgFirstBytes) {
            qWarning() << "第一帧必须是648bytes" << data.size();
            return;
        }

        m_frame.width = (static_cast<quint8>(data[4]) << 8) | static_cast<quint8>(data[5]);
        m_frame.height = (static_cast<quint8>(data[6]) << 8) | static_cast<quint8>(data[7]);

        m_hasHead = true;

        //如果第一帧收到的时候有内容，则认为之前的数据丢包了，不完整，直接丢弃
        m_frame.data = data;
        m_receivedPackets = 1;
    } else {
        // 非首包处理：需先收到帧头且总包数有效
        if (m_receivedPackets == 0 || !m_hasHead) {
            return;
        }

        m_frame.data.append(data);
        m_receivedPackets++;
    }

    // 检查帧是否完整
    if (m_receivedPackets >= m_totalPackets) {
        // 验证帧头
        if (static_cast<quint8>(m_frame.data[0]) != 0xF0 ||
            static_cast<quint8>(m_frame.data[1]) != 0x5A ||
            static_cast<quint8>(m_frame.data[2]) != 0xA5 ||
            static_cast<quint8>(m_frame.data[3]) != 0x0F ||
            m_frame.data.size() != m_imgAllBytes + 8) {
            qWarning() << "Invalid frame" << "actual size:" << m_frame.data.size();
            m_hasHead = false;
            return;
        }

        m_hasHead = false;

        // 每收到一行数据，帧数加1
        m_frameCount++;

        // 检查是否已经超过1秒，计算帧率
        if (m_fpsTimer.elapsed() >= 1000) {
            m_currentFps = m_frameCount * 1000.0 / m_fpsTimer.elapsed();
            qDebug() << "udp的一整帧发送至编码的速度:" << m_currentFps;

            // 重置计时器和计数器
            m_fpsTimer.restart();
            m_frameCount = 0;
        }

        //直接发送到编码端
        //emit sigToEncodeImg(m_frame.data.mid(8));

        //将完整帧存入队列，不直接emit
        QMutexLocker locker(&m_queueMutex); // 自动加锁/解锁，确保线程安全
        // 队列满时丢弃oldest帧
        if (m_frameQueue.size() >= m_maxQueueSize) {
            m_frameQueue.dequeue();
            qWarning() << "Frame queue is full! Drop oldest frame";
        }
        // 将帧数据加入队列
        m_frameQueue.enqueue(m_frame.data.mid(8));
    }
}

void GroundWVUdp::setTargetFps(int fps)
{
    if (fps <= 0) return;
   m_targetFps = fps;
   m_sendTimer.setInterval(1000 / m_targetFps); // 实时更新周期
}
